package com.treasure.mall.biz.service.core.user.impl;

import com.treasure.mall.biz.base.AbstractSearchableCrudService;
import com.treasure.mall.biz.base.AuthHelper;
import com.treasure.mall.biz.base.SpecificationAndSort;
import com.treasure.mall.biz.base.UserDetails;
import com.treasure.mall.biz.dto.BaseSaveDTO;
import com.treasure.mall.biz.dto.BaseSearchDTO;
import com.treasure.mall.biz.dto.condition.DepositLogCondition;
import com.treasure.mall.biz.entity.user.DepositLogPO;
import com.treasure.mall.biz.entity.user.DepositLogPO_;
import com.treasure.mall.biz.repository.user.DepositLogRepository;
import com.treasure.mall.biz.service.core.user.DepositLogService;
import com.treasure.mall.zbq.common.Jsr310Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author allan
 * @version 1.0.0
 * @date 2020/8/12
 */
@Service
public class DepositLogServiceImpl extends AbstractSearchableCrudService<DepositLogPO, Long> implements DepositLogService {
    @Autowired
    protected DepositLogServiceImpl(DepositLogRepository repository) {
        super(repository);
    }

    @Override
    protected SpecificationAndSort<DepositLogPO> specificationAndSort(BaseSearchDTO searchDTO) {
        DepositLogCondition condition = (DepositLogCondition) searchDTO;

        UserDetails userDetails = AuthHelper.getPrincipal();
        if (AuthHelper.isMerchant(userDetails)) {
            condition.setMerchantId(userDetails.getId());
        }

        Specification<DepositLogPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (condition.getMerchantId() > 0) {
                predicates.add(cb.equal(root.get(DepositLogPO_.merchantId), condition.getMerchantId()));
            }
            if (!StringUtils.isEmpty(condition.getOrderId())) {
                predicates.add(cb.equal(root.get(DepositLogPO_.orderId), condition.getOrderId()));
            }
            if (!StringUtils.isEmpty(condition.getBillId())) {
                predicates.add(cb.equal(root.get(DepositLogPO_.billId), condition.getBillId()));
            }
            if (!StringUtils.isEmpty(condition.getBeginTime())) {
                LocalDateTime beginTime = Jsr310Utils.DateTime.of(condition.getBeginTime());
                predicates.add(cb.greaterThanOrEqualTo(root.get(DepositLogPO_.createTime), beginTime));
            }
            if (!StringUtils.isEmpty(condition.getEndTime())) {
                LocalDateTime endTime = Jsr310Utils.DateTime.of(condition.getEndTime());
                predicates.add(cb.lessThanOrEqualTo(root.get(DepositLogPO_.createTime), endTime));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        Sort sort = new Sort(Sort.Direction.DESC, "createTime");

        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    public DepositLogPO save(BaseSaveDTO saveDTO) {
        return null;
    }
}
